package com.danieltoms.gcSync.google;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import javax.microedition.pim.Contact;
import javax.microedition.pim.ContactList;
import javax.microedition.pim.PIM;
import javax.microedition.pim.PIMException;

import net.rim.device.api.system.PersistentObject;
import net.rim.device.api.system.PersistentStore;
import net.rim.device.api.system.RuntimeStore;

import com.danieltoms.gcSync.contact.BBContact;

public class GoogleDataStore
{
	private static GoogleDataStore _instance = null;
	private Vector _syncMappingItems = null;
	private Hashtable _syncMappingItemsByBUID = null;
	private Hashtable _syncMappingItemsByGUID = null;

	private static final long GCSYNC_PERSISTENT_STORE_KEY = 0x187fcb0d778616acL;
	private static final long RUNTIME_STORE_KEY = 0x187fcb0d778616acL;
	private PersistentObject _store = null;

	static
	{
		// there can be two instances of this class, one for each app. we only
		// want one instance stored in the runtimestore
		if (RuntimeStore.getRuntimeStore().get(RUNTIME_STORE_KEY) == null)
			_instance = new GoogleDataStore();

	}

	public static GoogleDataStore instance()
	{
		return (GoogleDataStore) RuntimeStore.getRuntimeStore().get(RUNTIME_STORE_KEY);
	}

	public void commit()
	{
		_store.setContents(_syncMappingItems);
		_store.commit();
	}

	private GoogleDataStore()
	{
		_store = PersistentStore.getPersistentObject(GCSYNC_PERSISTENT_STORE_KEY);

		_syncMappingItems = (Vector) _store.getContents();

		if (_syncMappingItems == null)
			_syncMappingItems = new Vector();

		_syncMappingItemsByBUID = new Hashtable();
		_syncMappingItemsByGUID = new Hashtable();

		Enumeration sis = _syncMappingItems.elements();

		while (sis.hasMoreElements())
		{
			GoogleDataItem si = (GoogleDataItem) sis.nextElement();

			_syncMappingItemsByBUID.put(si.getBBUID(), si);

			// we could have unsynced adds
			if (si.getGoogleId() != null)
				_syncMappingItemsByGUID.put(si.getGoogleId(), si);

		}
		GoogleDataStore test = (GoogleDataStore) RuntimeStore.getRuntimeStore().get(RUNTIME_STORE_KEY);
		System.out.println(test);
		RuntimeStore.getRuntimeStore().put(RUNTIME_STORE_KEY, this);
	}

	public void print()
	{
		Enumeration e = _syncMappingItems.elements();

		int count = 0;
		System.out.println("Print GoogleDataItems");
		while (e.hasMoreElements())
		{
			GoogleDataItem si = (GoogleDataItem) e.nextElement();
			System.out.println("bbuid: " + si.getBBUID() + " guid: " + si.getGoogleId() + " state: " + si.getState());
			count++;
		}
		System.out.println("Total GoogleDataItems: " + count);
	}

	public void erase()
	{
		_syncMappingItems = new Vector();
		_syncMappingItemsByBUID = new Hashtable();
		_syncMappingItemsByGUID = new Hashtable();
		commit();
	}

	// on initial sync, add all contacts and set state to add
	public void initGoogleDataStore() throws PIMException
	{

		ContactList list = (ContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.READ_WRITE);

		Enumeration bbContacts = list.items();

		while (bbContacts.hasMoreElements())
		{
			BBContact bc = new BBContact((Contact) bbContacts.nextElement());

			GoogleDataItem si = new GoogleDataItem();
			si.setBBUID(bc.getUID());
			si.setState(GoogleDataItem.BB_ADD);
			addGoogleDataItem(si);
		}

	}

	public void addGoogleDataItem(GoogleDataItem si)
	{
		_syncMappingItems.addElement(si);
		if (si.getBBUID() != null)
			_syncMappingItemsByBUID.put(si.getBBUID(), si);
		if (si.getGoogleId() != null)
			_syncMappingItemsByGUID.put(si.getGoogleId(), si);
	}

	public GoogleDataItem getSyncItemByUID(String uid)
	{
		log(uid);
		log(new Integer(_syncMappingItemsByBUID.size()).toString());
		return (GoogleDataItem) _syncMappingItemsByBUID.get(uid);
	}

	public GoogleDataItem getSyncItemByGoogleID(String id)
	{
		return (GoogleDataItem) _syncMappingItemsByGUID.get(id);
	}

	public Enumeration getSyncMappings()
	{
		return _syncMappingItems.elements();
	}

	public int getPendingBBSyncCount()
	{
		// TODO this is slow
		int count = 0;
		
		Enumeration e = getSyncMappings();
		
		while(e.hasMoreElements())
		{
			GoogleDataItem gdi = (GoogleDataItem) e.nextElement();
			
			if(gdi.getState()!=GoogleDataItem.NA)
				count++;
		}
		
		return count;
		
	}
	
	private static void log(String msg)
	{
		System.out.println(msg);

	}

	public void removeGoogleDataItem(GoogleDataItem si)
	{
		_syncMappingItems.removeElement(si);
		_syncMappingItemsByBUID.remove(si.getBBUID());
		_syncMappingItemsByGUID.remove(si.getGoogleId());
	}

}
